package com.yic.module.device.service.inspectionPlanJob;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.yic.module.device.dal.dataobject.inspectionPlan.InspectionPlanDO;
import com.yic.module.device.enums.inspectionPlanDevice.CommonStatusEnum;
import com.yic.module.device.enums.inspectionPlanDevice.DeviceInspectionPlanType;
import com.yic.module.device.enums.inspectionPlanDevice.JobApiTypeEnum;
import com.yic.module.device.service.inspectionPlan.InspectionPlanService;
import com.yic.module.infra.api.job.JobApi;
import com.yic.module.infra.api.job.dto.JobApiDTO;
import com.yic.module.system.api.code.CodeApi;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;

import java.util.*;
import com.yic.module.device.controller.admin.inspectionPlanJob.vo.*;
import com.yic.module.device.dal.dataobject.inspectionPlanJob.InspectionPlanJobDO;
import com.yic.framework.common.pojo.PageResult;

import com.yic.module.device.convert.inspectionPlanJob.InspectionPlanJobConvert;
import com.yic.module.device.dal.mysql.inspectionPlanJob.InspectionPlanJobMapper;

import static com.yic.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.yic.module.device.enums.ErrorCodeConstants.*;

/**
 * 巡检计划与任务关联 Service 实现类
 *
 * @author 系统管理员
 */
@Service
@Validated
public class InspectionPlanJobServiceImpl implements InspectionPlanJobService {

    @Resource
    private InspectionPlanJobMapper inspectionPlanJobMapper;
    @Resource
    private InspectionPlanService inspectionPlanService;

    @Resource
    private JobApi jobApi;
    // 重试3次
    private static final Integer RETRY_COUNT = 3;
    // 重试间隔3分钟
    private static final Integer RETRY_INTERVAL = 3 * 60000;
    // 处理器的名字
    public static final String HANDLER_NAME = "inspectionPlanJob";


    @Override
    public Long createInspectionPlanJob(InspectionPlanJobCreateReqVO createReqVO) {
        // 获取巡检计划
        InspectionPlanDO inspectionPlan = inspectionPlanService.getInspectionPlan(createReqVO.getPlanId());
        if (inspectionPlan.getStatus().equals(CommonStatusEnum.DEACTIVATED.getCode())) {
            throw exception(UNABLE_TO_CREATE_TASK);
        }
        // 查询巡检计划是否已经创建定时任务
        InspectionPlanJobExportReqVO vo = new InspectionPlanJobExportReqVO();
        vo.setPlanId(createReqVO.getPlanId());
        if (CollectionUtil.isNotEmpty(inspectionPlanJobMapper.selectList(vo))) {
            throw exception(JOB_HAS_CREATED);
        }
        // 创建定时任务
        Long jobId = null;
        try {
            JobApiDTO jobApiDTO = new JobApiDTO();
            jobApiDTO.setName(inspectionPlan.getName() + "(序号" + inspectionPlan.getId() + ")");
            if (inspectionPlan.getType().equals(DeviceInspectionPlanType.INSPECTION_PLAN.getCode())){
                jobApiDTO.setType(String.valueOf(JobApiTypeEnum.INSPECTION_PLAN.getCode()));
            } else if(inspectionPlan.getType().equals(DeviceInspectionPlanType.MAINTENANCE_PLAN.getCode())){
                jobApiDTO.setType(String.valueOf(JobApiTypeEnum.MAINTENANCE_PLAN.getCode()));
            }
            jobApiDTO.setCronExpression(inspectionPlan.getCycle());
            jobApiDTO.setRetryCount(RETRY_COUNT);
            jobApiDTO.setRetryInterval(RETRY_INTERVAL);
            jobApiDTO.setHandlerParam(String.valueOf(inspectionPlan.getId()));
            jobApiDTO.setHandlerName(HANDLER_NAME + "#" + inspectionPlan.getId());
            jobId = jobApi.createJob(jobApiDTO);
            if (ObjectUtil.isNull(jobId)){
                throw exception(JOB_CREATE_FAIL);
            }
        } catch (Exception e) {
            throw exception(JOB_CREATE_FAIL);
        }
        // 添加巡检计划和定时任务关联信息
        createReqVO.setJobId(String.valueOf(jobId));
        createReqVO.setStatus(CommonStatusEnum.ENABLE.getCode());
        InspectionPlanJobDO inspectionPlanJob = InspectionPlanJobConvert.INSTANCE.convert(createReqVO);
        inspectionPlanJobMapper.insert(inspectionPlanJob);
        // 返回
        return inspectionPlanJob.getId();
    }

    @Override
    public void updateInspectionPlanJob(InspectionPlanJobUpdateReqVO updateReqVO) {
        // 校验存在
        validateInspectionPlanJobExists(updateReqVO.getId());
        // 更新
        InspectionPlanJobDO updateObj = InspectionPlanJobConvert.INSTANCE.convert(updateReqVO);
        inspectionPlanJobMapper.updateById(updateObj);
    }

    @Override
    public void deleteInspectionPlanJob(Long id) {
        // 校验存在
        validateInspectionPlanJobExists(id);
        InspectionPlanJobDO planJobDO = inspectionPlanJobMapper.selectById(id);
        // 删除定时任务
        try {
            jobApi.deleteJob(Long.valueOf(planJobDO.getJobId()));
        } catch (Exception e) {
            throw exception(TASK_FAILED_DELETED);
        }
        // 删除
        inspectionPlanJobMapper.deleteById(id);
    }

    private void validateInspectionPlanJobExists(Long id) {
        if (inspectionPlanJobMapper.selectById(id) == null) {
            throw exception(INSPECTION_PLAN_JOB_NOT_EXISTS);
        }
    }

    @Override
    public InspectionPlanJobDO getInspectionPlanJob(Long id) {
        return inspectionPlanJobMapper.selectById(id);
    }

    @Override
    public List<InspectionPlanJobDO> getInspectionPlanJobList(Collection<Long> ids) {
        return inspectionPlanJobMapper.selectBatchIds(ids);
    }

    @Override
    public PageResult<InspectionPlanJobDO> getInspectionPlanJobPage(InspectionPlanJobPageReqVO pageReqVO) {
        return inspectionPlanJobMapper.selectPage(pageReqVO);
    }

    @Override
    public List<InspectionPlanJobDO> getInspectionPlanJobList(InspectionPlanJobExportReqVO exportReqVO) {
        return inspectionPlanJobMapper.selectList(exportReqVO);
    }

}
